/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
/* 
This file contains the implementation for the Dynamic 2D char Array module. The
Dynamic 2D char array is a dynamically allocated array that can be 
indexed using two indexes, like a regular two-dimensional array in C.
See Dynamic2DCharArray.h for more details. 

This File was written as part of HW assignment 1 in the course Introduction
To Systems Programming at Tel-Aviv University's School of Electrical 
Engineering, Winter 2011, by Amnon Drory.
*/
/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/

#include <stdlib.h>

#include "Dynamic2DCharArray.h"

/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/

Dynamic2DCharArr CreateDynamic2DCharArr( unsigned int Height, unsigned int Width )
{
	unsigned int RowInd;	
	Dynamic2DCharArr Arr = NULL;
	LinePtr_Char* RowStartPointers = NULL;
	
	/* -------------------------------------------- */
	/* 1. Create an array of size Width*Height of   */
    /*    char. This will hold the data. */
	/* -------------------------------------------- */
	
	BasicType* RawData = 
		( BasicType * )malloc( Width*Height*sizeof( BasicType ));
	
	if ( RawData == NULL )
		return NULL;

	/* ------------------------------------------------ */
	/* 2. Create an array of pointers to row beginnings */
	/* ------------------------------------------------ */
	
	RowStartPointers = (LinePtr_Char*)malloc( Height*sizeof( LinePtr_Char ) );

	if ( RowStartPointers == NULL )
	{
		free(RawData);
		return NULL;
	}

	/* --------------------------------------------- */
	/* 3. initialize the RowStartPointers array to   */
	/*	  point to the beginnings of rows in RawData */
	/* --------------------------------------------- */
	
	RowStartPointers[0] = &( RawData[0] ); /* The beginning of the first row is */
	/* at the beginning of the RawData array */
	
	for ( RowInd = 1; RowInd < Height; RowInd++ )
	{
		RowStartPointers[RowInd] = RowStartPointers[RowInd-1] + Width; 
		/* Pointer Arithmetic: there are 'Width' cells in a row, so adding 'Width' */
		/* to a pointer that points to the beginning of row K, created a pointer */
		/* that points to the beginning of row K+1 */
	}

	Arr = &( RowStartPointers[0] );
	
	/* Arr is a pointer to the beginning of the RowStartPointers array. */
	/* Arr[i] is the i'th cell of the RowStartPointers array. It is actually */
	/*		  a pointer to the cell in RawData which is at the beginning of the */
	/*        i'th row. */
	/* Arr[i][j] is the cell in RawData which is on the i'th row and the j'th */
	/*           column */
	
	return Arr;
}

/*o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.*/

void FreeDynamic2DCharArr( Dynamic2DCharArr Arr )
{
	LinePtr_Char* RowStartPointers = NULL;	
	BasicType* RawData = NULL;

	if ( Arr == NULL )
		return;

	RowStartPointers = Arr;	
	RawData = RowStartPointers[0];

	free( RawData );
	free ( RowStartPointers );

}